#! /usr/bin/env python
#coding=utf-8

import os

from .builder import Builder

from .module_builder import ModuleBuilder

class ComponentBuilder(Builder):
	def _getUrlPrefix(self, context):
		product = context.xargs["_cur_product"]
		return os.path.join(product.getUrlPrefix(), "components", str(context.obj["id"]))

	def getGraphVizInfo(self, context):
		urlPrefix = self._getUrlPrefix(context)
		args = []
		for k in ("type", "format"):
			args.append("%s=%s" % (k, context.xargs[k]))
		args = "&amp;".join(args)
		fullUrl = os.path.join(urlPrefix, "fields") + "?" + args
		#labelStr = "<<u>%s</u>>" % context.obj.getDetailName()
		labelStr = '"%s"' % context.obj["name"]
		#labelStr = '"%s"' % context.obj["name"]
		return '"m%d" [style="rounded,filled", label=%s, href="%s"];\n' % (context.obj["id"], labelStr, fullUrl)

	def getGraphVizInfoForDeps(self, context):
		dep = context.obj
		linkStr = "javascript:top.fnEvtShowModuleDepsForComponent(%d, 'dep')" % dep["id"]
		labelStr = "<<u>%s</u>>" % str(len(dep["calls"])) # underline
		return "m%d -> m%d [label=%s, href=\"%s\", fontcolor=blue];\n" % (dep["caller"]["id"], dep["callee"]["id"], labelStr, linkStr)

	def _generateContextGraph(self, context):
		mod = context.obj
		dependedBy = mod["dependedBy"]
		for dep in dependedBy:
			m = dep["caller"]
			context.setObj(m)
			vizStr = self.getGraphVizInfo(context)
			context.f.write(vizStr)

		context.setObj(mod)
		vizStr = self.getGraphVizInfo(context)
		context.f.write(vizStr)

		for dep in mod["deps"]:
			context.setObj(dep["callee"])
			vizStr = self.getGraphVizInfo(context)
			context.f.write(vizStr)

		for dep in dependedBy + mod["deps"]:
			context.setObj(dep)
			vizStr = self.getGraphVizInfoForDeps(context)
			context.f.write(vizStr)

	def __plotModulesSubgraph(self, f, modules, name):
		if len(modules) == 0:
			return
		f.write("subgraph cluster_%s {\n" % name)
		f.write('corlor=blue\nlabel="%s"\n' % ModuleBuilder.getModuleGroupDesc(name))
		# loader.ElfModule.MODULE_TYPE_DESC
		for mod in modules:
			f.write(mod.getGraphVizInfo())
		f.write("}\n")

	def getGroupedModules(self, com):
		res = {}
		for t in ModuleBuilder.MODULE_GROUPS:
			res[t] = []

		for mod in com["modules"]:
			res[mod["modGroup"]].append(mod)

		return res

	def __plotAllNodesGraph(self, context):
		groups = self.getGroupedModules(context.obj)
		for name, val in groups.items():
			self.__plotModulesSubgraph(context.f, val, name)

	def _generateInternalDepGraph(self, context):
		self.__plotAllNodesGraph(context)
		for dep in context.obj["deps_internal"]:
			context.f.write("m%d -> m%d [label=\"%s\"];\n" % (dep["caller"]["id"], dep["callee"]["id"], str(dep["calls"])))

	def generateObjectGraph(self, context):
		if context.xargs["type"] in ("deps"):
			context.f.write("rankdir=\"LR\"\n")
		if context.xargs["type"] == "deps_internal":
			self._generateInternalDepGraph(context)
		else:
			self._generateContextGraph(context)
